package com.hgyc.mom.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hgyc.mom.common.enums.CommonStatus;
import com.hgyc.mom.system.entity.SysMenu;
import com.hgyc.mom.system.service.SysMenuService;
import com.hgyc.mom.system.service.SysRoleMenuService;
import com.hgyc.mom.system.vo.MenuVO;
import com.hgyc.mom.system.mapper.SysMenuMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统菜单 服务实现类
 * </p>
 *
 * @author fwj
 * @since 2025-01-16
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Override
    public List<MenuVO> all() {
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getStatus, CommonStatus.ENABLE.getValue())
                .orderByAsc(SysMenu::getSn);
        List<SysMenu> allMenu = list(wrapper);

        return this.convertToTree(allMenu);
    }

    @Override
    public List<MenuVO> getUserMenu(Long userId) {
        List<SysMenu> sysMenuList = baseMapper.getUserMenu(userId);
        return this.convertToTree(sysMenuList);
    }

    @Override
    public List<String> getUserPermissions(Long userId) {
        List<SysMenu> permissionList = baseMapper.getUserPermission(userId);
        return permissionList.stream()
                .map(SysMenu::getPermission)
                .filter(Objects::nonNull)
                .filter(Predicate.not(String::isEmpty))   // 过滤空字符串
                .collect(Collectors.toList());
    }

    @Override
    public List<MenuVO> getRoleMenu(Long roleId) {
        List<SysMenu> sysMenuList = baseMapper.getRoleMenu(roleId);
        return this.convertToTree(sysMenuList);
    }

    @Override
    public List<Long> roleAuth(Long roleId) {
        List<SysMenu> sysMenuList = baseMapper.roleAuth(roleId);

        return sysMenuList.stream().map(SysMenu::getId).collect(Collectors.toList());
    }

    @Override
    public SysMenu queryById(Long id) {
        return getById(id);
    }

    @Override
    public void deleteMenu(Long id) {
        // 删除子菜单
        deleteChildren(id);
        // 删除菜单本身
        baseMapper.deleteById(id);
        //删除角色关联的菜单
        sysRoleMenuService.deleteByMenuId(id);
    }

    private List<MenuVO> convertToTree(List<SysMenu> menus) {
        Map<Long, List<MenuVO>> parentChildrenMap = new HashMap<>();
        for (SysMenu menu : menus) {
            Long parentId = menu.getParentId();

            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(menu, menuVO);
            // 将当前菜单项添加到父菜单项的子菜单项列表中
            List<MenuVO> children = parentChildrenMap.getOrDefault(parentId, new ArrayList<>());
            children.add(menuVO);
            parentChildrenMap.put(parentId, children);

        }
        // 将根节点的子菜单项列表转换为树形结构
        List<MenuVO> rootChildren = parentChildrenMap.getOrDefault(0L, new ArrayList<>());
        for (MenuVO menu : rootChildren) {
            convertToTree(menu, parentChildrenMap);
        }
        return rootChildren;
    }

    private void convertToTree(MenuVO parent, Map<Long, List<MenuVO>> parentChildrenMap) {
        Long parentId = parent.getId();
        List<MenuVO> children = parentChildrenMap.getOrDefault(parentId, new ArrayList<>());
        parent.setChildren(children);
        for (MenuVO child : children) {
            convertToTree(child, parentChildrenMap);
        }
    }

    // 递归删除子菜单
    private void deleteChildren(Long parentId) {
        // 查询所有子菜单
        List<SysMenu> childMenus = baseMapper.selectList(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, parentId));
        for (SysMenu childMenu : childMenus) {
            // 递归删除子菜单的子菜单
            deleteChildren(childMenu.getId());
            // 删除当前子菜单
            baseMapper.deleteById(childMenu.getId());

            //删除角色关联的菜单
            sysRoleMenuService.deleteByMenuId(childMenu.getId());
        }
    }
}
